<template>
    <div ref="wrapper" style="overflow: hidden">
        <div>
            <div style="height: 45px;text-align: center; line-height: 45px" v-show="refreshing">
                <slot name="refreshing">
                    <inline-loading></inline-loading>
                    正在加载
                </slot>
            </div>
            <slot></slot>
            <div style="height: 45px;text-align: center; line-height: 45px" v-show="loading">
                <slot name="loading">
                    <inline-loading></inline-loading>
                    正在加载
                </slot>
            </div>
            <div v-show="finish">
                <slot name="done">
                    <divider slot="infinite-done">
                        暂无更多内容
                    </divider>
                </slot>
            </div>
        </div>
    </div>
</template>

<script>
    import BScroll from 'better-scroll'
    import {
        Divider,
        InlineLoading
    } from 'vux'

    export default {
        name: 'scroll',
        components: {
            Divider,
            InlineLoading
        },
        data: function () {
            return {
                beforePullDown: false,
                refreshing: false,
                loading: false,
                finish: false,
                pageNum: 1,
            }
        }
        ,
        props: {
            //分页
            total: {
                type: [Number],
                default: 0
            },
            pageSize: {
                type: [Number],
                default: 20
            },
            /**
             * 1 滚动的时候会派发scroll事件，会截流。
             * 2 滚动的时候实时派发scroll事件，不会截流。
             * 3 除了实时派发scroll事件，在swipe的情况下仍然能实时派发scroll事件
             */
            probeType: {
                type: Number,
                default: 1
            },
            /**
             * 点击列表是否派发click事件
             */
            click: {
                type: Boolean,
                default: true
            },
            /**
             * 是否开启横向滚动
             */
            scrollX: {
                type: Boolean,
                default: false
            },
            /**
             * 是否派发滚动事件
             */
            listenScroll: {
                type: Boolean,
                default: false
            },
            /**
             * 列表的数据
             */
            data: {
                type: Array,
                default: null
            },
            /**
             * 是否派发滚动到底部的事件，用于上拉加载
             */
            pullup: {
                type: Boolean,
                default: false
            },
            /**
             * 是否派发顶部下拉的事件，用于下拉刷新
             */
            pulldown: {
                type: Boolean,
                default: false
            },
            /**
             * 是否派发列表滚动开始的事件
             */
            beforeScroll: {
                type: Boolean,
                default: false
            },
            /**
             * 当数据更新后，刷新scroll的延时。
             */
            refreshDelay: {
                type: Number,
                default: 20
            }
        },
        mounted() {
            this._initScroll()

            //监听元素加载完成
            new MutationObserver((records) => {
                this.refresh()
                this.loading = false
            }).observe(this.$refs.wrapper, {
                childList: true,
                subtree: true,
                attributesFilter: ['length']
            })
        },
        computed: {
            totalPage: function () {
                return Math.ceil(this.total / this.pageSize)
            }
        },
        methods: {
            done: function () {
                this.loading = false
                this.refreshing = false
                this.scroll.finishPullDown()
            },

            //上拉加载
            downRefresh: function () {
                if (this.loading || this.refreshing) {
                    return
                }

                if (this.pageNum >= this.totalPage) {
                    this.finish = true
                    return
                }


                this.loading = true
                this.pageNum++

                this.$emit('on-infinite', this.pageNum, this.done)
            },

            _initScroll() {
                if (!this.$refs.wrapper) {
                    return
                }
                // better-scroll的初始化
                this.scroll = new BScroll(this.$refs.wrapper, {
                    probeType: this.probeType,
                    click: this.click,
                    scrollX: this.scrollX,
                    pullDownRefresh: this.pulldown,
                    preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|DIV)$/}
                })


                if (this.pulldown) {
                    this.scroll.on('pullingDown', () => {
                        if (this.loading || this.refreshing) {
                            return
                        }

                        if (Math.floor((this.pageNum - 1) / 3) <= 0) {
                            this.scroll.finishPullDown()
                            return
                        }

                        this.refreshing = true
                        this.pageNum = Math.floor((this.pageNum - 1) / 3) * 3 + 1 - 3
                        this.$emit('pullingDown', this.pageNum, this.done)
                    })
                }


                this.scroll.on('scroll', (pos) => {
                    if (this.beforePullDown) {
                        this.bubbleY = Math.max(0, pos.y + this.pullDownInitTop)
                        this.pullDownStyle = `top:${Math.min(pos.y + this.pullDownInitTop, 10)}px`
                    } else {
                        this.bubbleY = 0
                    }

                    if (this.isRebounding) {
                        this.pullDownStyle = `top:${10 - (this.pullDownRefresh.stop - pos.y)}px`
                    }
                })

                // 是否派发滚动到底部事件，用于上拉加载
                if (true) {
                    this.scroll.on('scrollEnd', () => {
                        // 滚动到底部
                        if (this.scroll.y <= (this.scroll.maxScrollY + 50)) {
                            this.downRefresh()
                        }
                    })
                }

            },
            disable() {
                // 代理better-scroll的disable方法
                this.scroll && this.scroll.disable()
            },
            enable() {
                // 代理better-scroll的enable方法
                this.scroll && this.scroll.enable()
            },
            refresh() {
                // 代理better-scroll的refresh方法
                this.scroll && this.scroll.refresh()
            },
            scrollTo(page) {
                // 代理better-scroll的scrollTo方法
                this.scroll && this.scroll.scrollTo(0, 0, 1000)
            },
            scrollToElement() {
                // 代理better-scroll的scrollToElement方法
                this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
            }
        },
//        watch: {
//            // 监听数据的变化，延时refreshDelay时间后调用refresh方法重新计算，保证滚动效果正常
//            data() {
//                setTimeout(() => {
//                    this.refresh()
//                }, this.refreshDelay)
//            }
//        }
    }
</script>
